/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package model;

import gui.InfoBord;
import gui.Vak;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

/**
 *
 * @author Stijn Delbeke
 */
public class Spel {

    public final static String ROOD = "Rood";
    public final static String BLAUW = "Blauw";
    private ArrayList<Stuk> legerRood = new ArrayList<Stuk>();
    private ArrayList<Stuk> legerBlauw = new ArrayList<Stuk>();
    private final int VLAG = 1;
    private final int MAARSCHALK = 1;
    private final int GENERAAL = 1;
    private final int KOLONEL = 2;
    private final int MAJOOR = 3;
    private final int KAPITEIN = 4;
    private final int LUITENANT = 4;
    private final int SERGEANT = 4;
    private final int MINEUR = 5;
    private final int VERKENNER = 8;
    private final int SPION = 1;
    private final int BOM = 6;
    private final int NOORD = 1;
    private final int OOST = 2;
    private final int ZUID = 3;
    private final int WEST = 4;
    private Vak[][] vakken;
    private String beurt = ROOD;
    private InfoBord infobord;
    private boolean rivaalIsMens;
    Random rnd = new Random(System.currentTimeMillis());
    private List<Integer> richtingen = Arrays.asList(NOORD, OOST, ZUID, WEST);
    private Vak kleurBron;
    private Vak kleurDoel;

    public Spel() {
        maakPionnen();
        maakVakken();
    }

    public void setInfobord(InfoBord infobord) {
        this.infobord = infobord;
    }

    public ArrayList<Stuk> getLeger(String s) {
        ArrayList<Stuk> army = null;
        if (s.equals(ROOD)) {
            army = legerRood;
        }
        else if (s.equals(BLAUW)) {
            army = legerBlauw;
        }

        return army;
    }

    public boolean getRivaalIsMens() {
        return rivaalIsMens;
    }

    public void setRivaalIsMens(boolean rivaalIsMens) {
        this.rivaalIsMens = rivaalIsMens;
    }

    public String getBeurt() {
        return beurt;
    }

    public void setBeurt(String beurt) {
        this.beurt = beurt;
    }

    public Vak[][] getVakken() {
        return vakken;
    }

    private void maakVakken() {
        vakken = new Vak[10][10];

        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                vakken[i][j] = new Vak();
                vakken[i][j].setHorizontalAlignment(JLabel.CENTER);
                vakken[i][j].setVerticalAlignment(JLabel.CENTER);
                vakken[i][j].setxPos(j);
                vakken[i][j].setyPos(i);
            }
        }
        //Water
        for (int i = 4; i <= 5; i++) {
            for (int j = 2; j <= 3; j++) {
                vakken[i][j].setLand(false);
                vakken[i][j].setBackground(Color.BLUE);
            }
            for (int j = 6; j <= 7; j++) {
                vakken[i][j].setLand(false);
                vakken[i][j].setBackground(Color.BLUE);
            }
        }
    }

    private void maakPionnen() {
        for (int i = 0; i < VLAG; i++) {
            legerRood.add(new Stuk(PionType.VLAG));
            legerBlauw.add(new Stuk(PionType.VLAG));
        }

        for (int i = 0; i < MAARSCHALK; i++) {
            legerRood.add(new Stuk(PionType.MAARSCHALK));
            legerBlauw.add(new Stuk(PionType.MAARSCHALK));
        }

        for (int i = 0; i < GENERAAL; i++) {
            legerRood.add(new Stuk(PionType.GENERAAL));
            legerBlauw.add(new Stuk(PionType.GENERAAL));
        }

        for (int i = 0; i < KOLONEL; i++) {
            legerRood.add(new Stuk(PionType.KOLONEL));
            legerBlauw.add(new Stuk(PionType.KOLONEL));
        }

        for (int i = 0; i < MAJOOR; i++) {
            legerRood.add(new Stuk(PionType.MAJOOR));
            legerBlauw.add(new Stuk(PionType.MAJOOR));
        }

        for (int i = 0; i < KAPITEIN; i++) {
            legerRood.add(new Stuk(PionType.KAPITEIN));
            legerBlauw.add(new Stuk(PionType.KAPITEIN));
        }

        for (int i = 0; i < LUITENANT; i++) {
            legerRood.add(new Stuk(PionType.LUITENANT));
            legerBlauw.add(new Stuk(PionType.LUITENANT));
        }

        for (int i = 0; i < SERGEANT; i++) {
            legerRood.add(new Stuk(PionType.SERGEANT));
            legerBlauw.add(new Stuk(PionType.SERGEANT));
        }

        for (int i = 0; i < MINEUR; i++) {
            legerRood.add(new Stuk(PionType.MINEUR));
            legerBlauw.add(new Stuk(PionType.MINEUR));
        }

        for (int i = 0; i < VERKENNER; i++) {
            legerRood.add(new Stuk(PionType.VERKENNER));
            legerBlauw.add(new Stuk(PionType.VERKENNER));
        }

        for (int i = 0; i < SPION; i++) {
            legerRood.add(new Stuk(PionType.SPION));
            legerBlauw.add(new Stuk(PionType.SPION));
        }

        for (int i = 0; i < BOM; i++) {
            legerRood.add(new Stuk(PionType.BOM));
            legerBlauw.add(new Stuk(PionType.BOM));
        }

    }

    public void verplaatsPion(Vak bron, Vak doel) {
        doel.setPion(bron.getPion());
        doel.setIcon(bron.getIcon());

        if (kleurBron != null && kleurDoel != null) {
            kleurBron.setBackground(Color.LIGHT_GRAY);
            kleurDoel.setBackground(Color.LIGHT_GRAY);
        }
        kleurBron = bron;
        kleurBron.setBackground(Color.GRAY);
        kleurDoel = doel;
        kleurDoel.setBackground(Color.GREEN);
        bron.removePion();


    }

    public void wijzigSpeler() {
        if (beurt.equals(ROOD)) {
            beurt = BLAUW;
            if (!rivaalIsMens) {
                computerZet();
                wijzigSpeler();
            }
        }
        else {
            beurt = ROOD;
        }
    }

    private void computerZet() {
        int i = rnd.nextInt(10);
        int j = rnd.nextInt(10);
        while (!vakken[i][j].bevatPion() || vakken[i][j].getPion().getLeger().equals(ROOD) || vakken[i][j].getPion().getType().equals(PionType.BOM) || vakken[i][j].getPion().getType().equals(PionType.VLAG)) {
            i = rnd.nextInt(10);
            j = rnd.nextInt(10);
        }

        Vak bron = vakken[i][j];
        Vak doel = null;

        Collections.shuffle(richtingen);

        int mogelijkeZet = 0;
        int aantStappen = 1;
        if (bron.getPion().getType().equals(PionType.VERKENNER)) {
            aantStappen = rnd.nextInt(8) + 1;
        }

        for (int k = 0; k < 4; k++) {
            int richting = richtingen.get(k);

            switch (richting) {
                case NOORD:
                    if (i > aantStappen && isGeldigeZet(vakken[i][j], vakken[i - aantStappen][j])) {
                        doel = vakken[i - aantStappen][j];
                        mogelijkeZet = richting;
                    }

                    break;
                case OOST:
                    if (j < (10 - aantStappen) && isGeldigeZet(vakken[i][j], vakken[i][j + aantStappen])) {
                        doel = vakken[i][j + aantStappen];
                        mogelijkeZet = richting;
                    }

                    break;
                case ZUID:
                    if (i < (10 - aantStappen) && isGeldigeZet(vakken[i][j], vakken[i + aantStappen][j])) {
                        doel = vakken[i + aantStappen][j];
                        mogelijkeZet = richting;
                    }

                    break;
                case WEST:
                    if (j > aantStappen && isGeldigeZet(vakken[i][j], vakken[i][j - aantStappen])) {
                        doel = vakken[i][j - aantStappen];
                        mogelijkeZet = richting;
                    }

                    break;
            }
        }
        if (mogelijkeZet == 0 || doel == null) {
            computerZet();
        }
        else {
            if (doel.bevatPion()) {
                battle(bron, doel);
            }
            else {
                verplaatsPion(bron, doel);
            }
        }
    }

    public void battle(Vak bron, Vak doel) {
        PionType aanvaller = bron.getPion().getType();
        PionType verdediger = doel.getPion().getType();
        JOptionPane.showMessageDialog(null, bron.getPion().getLeger() + ":  " + aanvaller.getNaam() + " \n     ---------------------------------------     \n " + doel.getPion().getLeger() + ":  " + verdediger.getNaam(), "Veldslag", JOptionPane.INFORMATION_MESSAGE);
        if (aanvaller.equals(verdediger)) {
            infobord.vermeerderPion(aanvaller, bron.getPion().getLeger());
            infobord.vermeerderPion(verdediger, doel.getPion().getLeger());
            bron.removePion();
            doel.removePion();

            JOptionPane.showMessageDialog(null, "Zelfmoord!", "Veldslag", JOptionPane.INFORMATION_MESSAGE);
        }
        else {
            if (doel.getPion().getType().equals(PionType.VLAG)) {
                eindeSpel();
            }
            else if (aanvaller.verslaat(verdediger)) {
                infobord.vermeerderPion(verdediger, doel.getPion().getLeger());
                JOptionPane.showMessageDialog(null, bron.getPion().getLeger() + ":  " + aanvaller.getNaam() + " wint!", "Veldslag", JOptionPane.INFORMATION_MESSAGE);
                doel.removePion();
                verplaatsPion(bron, doel);

            }
            else {
                infobord.vermeerderPion(aanvaller, bron.getPion().getLeger());
                JOptionPane.showMessageDialog(null, doel.getPion().getLeger() + ":  " + verdediger.getNaam() + " wint!", "Veldslag", JOptionPane.INFORMATION_MESSAGE);
                bron.removePion();

            }
            bron.repaint();
            doel.repaint();
        }
    }

    public boolean isGeldigeZet(Vak bron, Vak doel) {
        Stuk pion = bron.getPion();
        if (!doel.isLand()) {
            return false;
        }
        else if (pion.getType().equals(PionType.VLAG) || pion.getType().equals(PionType.BOM)) {
            return false;
        }
        else if (doel.bevatPion() && doel.getPion().getLeger().equals(bron.getPion().getLeger())) {
            return false;
        }
        else if (pion.getType().equals(PionType.VERKENNER)) {
            //De verkenner mag over heel het veld verlopen, op voorwaarde dat er niemand tussen zit
            if (((Math.abs(doel.getxPos() - bron.getxPos()) > 0) && Math.abs(doel.getyPos() - bron.getyPos()) == 0) || ((Math.abs(doel.getyPos() - bron.getyPos()) > 0) && Math.abs(doel.getxPos() - bron.getxPos()) == 0)) {
                return verkennerZetGeldig(bron, doel);
            }
            else {
                return false;
            }
        }
        else {
            final int STAP = 1;
            //Gewone pionnen mogen één stap per beurt zetten
            if (((Math.abs(doel.getxPos() - bron.getxPos()) == STAP) && Math.abs(doel.getyPos() - bron.getyPos()) == 0) || ((Math.abs(doel.getyPos() - bron.getyPos()) == STAP) && Math.abs(doel.getxPos() - bron.getxPos()) == 0)) {

                return true;
            }
            else {
                return false;
            }
        }
    }

    private boolean verkennerZetGeldig(Vak bron, Vak doel) {
        int bronX = bron.getxPos();
        int bronY = bron.getyPos();
        int doelX = doel.getxPos();
        int doelY = doel.getyPos();

        boolean zetGeldig = true;
        if (bronX - doelX == 0) {
            if (bronY < doelY) {
                for (int i = bronY + 1; i < doelY; i++) {
                    if (vakken[i][bronX].bevatPion() || !vakken[i][bronX].isLand()) {
                        zetGeldig = false;
                    }
                }
            }
            else {
                for (int i = doelY + 1; i < bronY; i++) {
                    if (vakken[i][bronX].bevatPion() || !vakken[i][bronX].isLand()) {
                        zetGeldig = false;
                    }
                }
            }
        }
        else if (bronY - doelY == 0) {
            if (bronX < doelX) {
                for (int i = bronX + 1; i < doelX; i++) {
                    if (vakken[bronY][i].bevatPion() || !vakken[bronY][i].isLand()) {
                        zetGeldig = false;
                    }
                }
            }
            else {
                for (int i = doelX + 1; i < bronX; i++) {
                    if (vakken[bronY][i].bevatPion() || !vakken[bronY][i].isLand()) {
                        zetGeldig = false;
                    }
                }
            }
        }
        return zetGeldig;
    }

    private void eindeSpel() {
        JOptionPane.showMessageDialog(null, getBeurt() + " wint het spel!", "Einde spel", JOptionPane.INFORMATION_MESSAGE);
        System.exit(0);
    }
}
